package com.jmp.push;

import com.gexin.rp.sdk.base.IBatch;
import com.gexin.rp.sdk.base.IPushResult;
import com.gexin.rp.sdk.base.IQueryResult;
import com.gexin.rp.sdk.base.ITemplate;
import com.gexin.rp.sdk.base.impl.AppMessage;
import com.gexin.rp.sdk.base.impl.ListMessage;
import com.gexin.rp.sdk.base.impl.SingleMessage;
import com.gexin.rp.sdk.base.impl.Target;
import com.gexin.rp.sdk.base.notify.Notify;
import com.gexin.rp.sdk.base.payload.APNPayload;
import com.gexin.rp.sdk.dto.GtReq;
import com.gexin.rp.sdk.exceptions.RequestException;
import com.gexin.rp.sdk.http.IGtPush;
import com.gexin.rp.sdk.template.TransmissionTemplate;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author cjr
 */
@Slf4j
public class DefaultPushClient implements PushClient {
    private static String url = "http://sdk.open.api.igexin.com/apiex.htm";
    private String appId;
    private String appKey;
    private String packageStr;
    private IGtPush push;

    public DefaultPushClient(OnePushProperties.OnePush onePush) {
        this.appId = onePush.getAppId();
        this.appKey = onePush.getAppKey();
        this.packageStr = onePush.getPackageStr();
        push = new IGtPush(url, appKey, onePush.getMasterSecret());
    }

    @Override
    public String getAppId() {
        return this.appId;
    }

    @Override
    public List<String> getAppIds() {
        return Lists.newArrayList(this.appId);
    }

    @Override
    public String getAppId(String clientKey) {
        return this.appId;
    }

    @Override
    public void toOne(PushClientRequest request) {
        ITemplate template = getTemplate(request.getTitle(), request.getContent(), request.getPayloadContent());

        SingleMessage message = new SingleMessage();
        message.setOffline(true);
        message.setOfflineExpireTime(24 * 3600 * 1000);// 离线有效时间，单位为毫秒，可选
        message.setData(template);
        message.setPushNetWorkType(0);// 可选，1为wifi，0为不限制网络环境。根据手机处于的网络情况，决定是否下发

        Target target = new Target();
        target.setAppId(appId);
        target.setClientId(request.getCid());
        //target.setAlias(Alias);

        IPushResult ret;
        try {
            ret = push.pushMessageToSingle(message, target);
        } catch (RequestException e) {
            log.error(e.getMessage(), e);
            ret = push.pushMessageToSingle(message, target, e.getRequestId());
        }
        if (ret != null) {
            log.info("push response: {}", ret.getResponse().toString());
        } else {
            log.error("服务器响应异常");
        }
    }

    @Override
    public void toOneBatch(List<PushClientRequest> requests) {
        IBatch batch = push.getBatch();

        IPushResult ret = null;
        try {
            for (PushClientRequest pushRequest : requests) {
                constructClientTransMsg(pushRequest, batch);
            }
            ret = batch.submit();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            try {
                ret = batch.retry();
            } catch (IOException ex) {
                log.error(e.getMessage(), e);
            }
        }
        if (ret != null) {
            log.info("push response: {}", ret.getResponse().toString());
        } else {
            log.error("服务器响应异常");
        }
    }

    public void toList(PushListRequest pushListRequest) {
        String taskId = getContentId(pushListRequest.getTitle(), pushListRequest.getContent(), pushListRequest.getPayloadContent());
        // 配置推送目标
        List<Target> targets = new ArrayList<>();
        Target target1;
        for (PushListRequest.PushTarget pushTarget : pushListRequest.getCids()) {
            target1 = new Target();
            target1.setAppId(appId);
            target1.setClientId(pushTarget.getCid());
            targets.add(target1);
        }

        IPushResult ret = null;
        try {
            ret = push.pushMessageToList(taskId, targets);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (ret != null) {
            log.info("push response: {}", ret.getResponse().toString());
        } else {
            log.error("服务器响应异常");
        }
    }

    @Override
    public void toAll(PushClientRequest request) {
        ITemplate template = getTemplate(request.getTitle(), request.getContent(), request.getPayloadContent());

        List<String> appIds = new ArrayList<String>();
        appIds.add(appId);

        // 定义"AppMessage"类型消息对象，设置消息内容模板、发送的目标App列表、是否支持离线发送、以及离线消息有效期(单位毫秒)
        AppMessage message = new AppMessage();
        message.setData(template);
        message.setAppIdList(appIds);
        message.setOffline(true);
        message.setOfflineExpireTime(1000 * 600);

        IPushResult ret = push.pushMessageToApp(message);
        if (ret != null) {
            log.info("push response: {}", ret.getResponse().toString());
        } else {
            log.error("服务器响应异常");
        }
    }

    public void getUserStatus(String cid) {
        IQueryResult abc = push.getClientIdStatus(appId, cid);
        log.info("status({}): {}", cid, abc.getResponse());
    }

    public void getPushResult(String taskId) {
        Map<String, Object> res = (Map<String, Object>) push.getPushResult(taskId).getResponse();
        for (Map.Entry<String, Object> entry : res.entrySet()) {
            log.info("{} {}", entry.getKey(), entry.getValue());
        }
    }

    private void constructClientTransMsg(PushClientRequest pushRequest, IBatch batch) throws Exception {
        ITemplate template = getTemplate(pushRequest.getTitle(), pushRequest.getContent(), pushRequest.getPayloadContent());

        SingleMessage message = new SingleMessage();
        message.setOffline(true);
        message.setOfflineExpireTime(24 * 3600 * 1000);// 离线有效时间，单位为毫秒，可选
        message.setData(template);
        message.setPushNetWorkType(0);// 可选，1为wifi，0为不限制网络环境。根据手机处于的网络情况，决定是否下发

        Target target = new Target();
        target.setAppId(appId);
        target.setClientId(pushRequest.getCid());

        batch.add(message, target);
    }

    /**
     * 用于在推送时去查找对应的message
     *
     * @return
     */
    private String getContentId(String title, String content, String payloadContent) {
        ITemplate template = getTemplate(title, content, payloadContent);
        ListMessage message = new ListMessage();
        message.setData(template);
        // 设置消息离线，并设置离线时间
        message.setOffline(true);
        // 离线有效时间，单位为毫秒，可选
        message.setOfflineExpireTime(24 * 1000 * 3600);
        message.setPushNetWorkType(0);//判断客户端是否wifi环境下推送。1为仅在wifi环境下推送，0为不限制网络环境，默认不限
        message.setPriority(1);
        return push.getContentId(message);
    }

    private ITemplate getTemplate(String title, String content, String payloadContent) {
        if (StringUtils.isBlank(payloadContent)) {
            payloadContent = StringUtils.EMPTY;
        }

        TransmissionTemplate template = new TransmissionTemplate();

        // 透传消息设置
        String payload = "{\"title\":\"" + title + "\",\"content\":\"" + content + "\",\"payload\":\"" + payloadContent + "\"}";
        log.debug("payload: {}", payload);
        template.setAppId(appId);
        template.setAppkey(appKey);
        template.setTransmissionContent(payload);
        template.setTransmissionType(2);//设置，1为强制启动应用，客户端接收到消息后就会立即启动应用；2为等待应用启动

        APNPayload payloadIOS = new APNPayload();
        //在已有数字基础上加1显示，设置为-1时，在已有数字上减1显示，设置为数字时，显示指定数字
        payloadIOS.setAutoBadge("+1");
        payloadIOS.setContentAvailable(0);// 0 receive 1 click
        payloadIOS.setSound("default");//ios 12.0 以上可以使用 Dictionary 类型的 sound
//        payloadIOS.setCategory("$由客户端定义");
        payloadIOS.addCustomMsg("payload", payloadContent.replaceAll("\\\\", ""));

        APNPayload.DictionaryAlertMsg alertMsg = new APNPayload.DictionaryAlertMsg();
        alertMsg.setTitle(title);
        alertMsg.setBody(content);
//        alertMsg.setActionLocKey("ActionLockey");
//        alertMsg.setLocKey("LocKey");
//        alertMsg.addLocArg("loc-args");
//        alertMsg.setLaunchImage("launch-image");
        // iOS8.2以上版本支持
//        alertMsg.setTitleLocKey("TitleLocKey");
//        alertMsg.addTitleLocArg("TitleLocArg");
        payloadIOS.setAlertMsg(alertMsg);
        template.setAPNInfo(payloadIOS);

        //设置第三方通知
        String intent = "intent:#Intent;launchFlags=0x14000000;package=com.pp.yl;component=" + packageStr + "/com.getui.demo.MainActivity;S.UP-OL-SU=true;S.title=" + title + ";S.content=" + content + ";S.payload=" + payloadContent + ";end";
//        String intent = "intent:#Intent;launchFlags=0x14000000;package=com.pp.yl;component=" + packageStr + ";S.UP-OL-SU=true;S.title=" + title + ";S.content=" + content + ";S.payload=test;end";
        log.debug("intent: {}", intent);
        Notify notify = new Notify();
        notify.setTitle(title);
        notify.setContent(content);
        notify.setIntent(intent);
        notify.setType(GtReq.NotifyInfo.Type._intent);
        //notify.setUrl("https://dev.getui.com/");
        //notify.setType(Type._url);
        template.set3rdNotifyInfo(notify);

        return template;
    }
}
